"use strict";

const roomMgr = require("../roomMgr");
const clientMgr = require("../clientMgr");
const socket = require('../../base_net/socket');
const crypto = require('../../utils/crypto');
const logger = require("../../utils/logger");
const db = require("../../utils/db");
var utils = require("../../utils/utils");

var games = {};
var gameSeatsOfUsers = {};
//超过半小时自动解散
var  kickList = {};

var ZJHOperate = {
    CALL: 1 << 2,
    RAISE: 1 << 3,
    COMPARE: 1 << 4,
    WATCH: 1 << 1,
    WAIVE: 1 << 0,
}

var ZJHOptionalOperate = {
    CALL_RAISE_COMPARE: ZJHOperate.CALL | ZJHOperate.RAISE | ZJHOperate.COMPARE | ZJHOperate.WAIVE,
    CALL_RAISE_COMPARE_WATCH: ZJHOperate.CALL | ZJHOperate.RAISE | ZJHOperate.COMPARE | ZJHOperate.WATCH | ZJHOperate.WAIVE,
    CALL_RAISE: ZJHOperate.CALL | ZJHOperate.RAISE | ZJHOperate.WAIVE,
    CALL_RAISE_WATCH: ZJHOperate.CALL | ZJHOperate.RAISE | ZJHOperate.WATCH | ZJHOperate.WAIVE,
    COMPARE: ZJHOperate.COMPARE | ZJHOperate.WAIVE,
    COMPARE_WATCH: ZJHOperate.COMPARE | ZJHOperate.WATCH | ZJHOperate.WAIVE,
    CALL: ZJHOperate.CALL | ZJHOperate.WAIVE,
    CALL_WATCH: ZJHOperate.CALL | ZJHOperate.WATCH | ZJHOperate.WAIVE,
}

exports.setReady = function(userId,value){
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var roomInfo = roomMgr.getRoom(roomId);
    if(roomInfo == null){
        return;
    }
    var seatIndex = roomMgr.getUserIndex(userId);
    if(seatIndex == null){
        return;
    }
    var s = roomInfo.seats[seatIndex];
    s.ready = value?true:false;
    clientMgr.broadcastInRoom(socket.resp.user_ready,{userId:userId,ready:value},userId,true);
    if((kickList[userId] || kickList[userId] >= 0) && s.sit == 1){
        delete kickList[userId];
    }

    var game = games[ roomId ];
    if( game == null ) {
        var count = 0;
        for( var i = 0; i < roomInfo.seats.length; ++i ) {
            var s = roomInfo.seats[ i ];
            if( s && s.userId > 0 && s.sit == 1){
                if(s.ready == false){
                    if(roomInfo.conf.maxGames > 0)return;
                    continue;
                }
                count ++;
            }
        }
        if(count <= 1)return;
        if(roomInfo.numOfGames == 0){
            roomMgr.setStart( roomId );
        }
        logger.game_log("启动炸金花游戏");
        //人数已经到齐了，并且都准备好了，则开始新的一局
        begin( roomId );
    }
}

exports.gameBegin = function(roomInfo){
    var roomId = roomInfo.roomId;
    if(roomInfo.numOfGames == 0){
        roomMgr.setStart( roomId );
    }
    logger.game_log("启动炸金花游戏");
    //人数已经到齐了，并且都准备好了，则开始新的一局
    var game = games[ roomId ];
    if( game == null ) {
        begin(roomId);
    }
}
exports.sitDown = function(userId,value){
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var roomInfo = roomMgr.getRoom(roomId);
    if(roomInfo == null){
        return;
    }
    var seatIndex = roomMgr.getUserIndex(userId);
    if(seatIndex == null){
        return;
    }

    var s = roomInfo.seats[seatIndex];
    s.sit = value == false?0:1;
    getNiuniu2(userId);
    clientMgr.broadcastInRoom(socket.resp.user_sit,{userId:userId,sit:s.sit},userId,true);

    if(roomInfo.numOfGames > 0 || roomInfo.conf.maxGames <= 0){
        delete kickList[userId];
    }
}
exports.syncInfo = function(userId){
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var roomInfo = roomMgr.getRoom(roomId);
    if(roomInfo == null || roomInfo.numOfGames == 0){
        return;
    }
    logger.game_log("同步扎金花");

    var game = games[ roomId ];
    var data = {};
    if( game != null ) {
        var ddd = game.gameSeats[game.button];

        data = {
            state : game.state,
            fundPool : game.fundPool,
            gameState:roomInfo.gameState,
            button : ddd != null?ddd.userId:0,
        };

        data.callNowCost = game.callNowCost;
        data.betTop = game.betTop;
        if (game.turnGamber != null) {
            data.gamber = game.gameSeats[game.turnGamber].userId;
            data.operates = getOptionalOperate(game, game.turnGamber);
        }
        data.seats = [];
        for(var i = 0; i < roomInfo.conf.roomNum; ++i) {
            var rs = roomInfo.seats[i];
            var sd = game.gameSeats[i];
            if( !sd ) continue;
            
            if(sd.userId == userId){
                rs.exitAfterEnd = false;
            }

            var s = {
                userId:sd.userId,
                scoreBetting : sd.scoreBetting,
                hasEliminate : sd.eliminate,
                hasBetting: sd.hasBetting,
                totalBetting: sd.score,
                // hasXia : sd.hasXia,
                // score2 : sd.score2,
                // hasLiang : sd.hasLiang,
                sit : sd.sit,
                ready : rs.ready,
            }

            var holds = null;
            if(data.state == 5){
                holds = sd.holds;
                var niu = calculate(holds);
                s.niu = niu;
            }
            else{
                if(sd.sit == 1 && sd.userId == userId){
                    if (sd.watchCardRound != null) {
                        holds = utils.clone(sd.holds);
                        data.callNowCost = game.callNowCost*2;
                        data.betTop = game.betTop*2;
                    }
                    // holds[holds.length-1] = -1;
                }
            }
            s.holds = holds;
            data.seats.push(s);
        }
    }
    else{
        data = {
            state : 0,
            gameState:roomInfo.gameState,
        };
        data.seats = [];
        for(var i = 0; i < roomInfo.conf.roomNum; ++i) {
            var sd = roomInfo.seats[i];
            if( sd.userId <= 0 ) continue;

            var s = {
                userId:sd.userId,
                ready : sd.ready,
                sit : sd.sit,
            }
            data.seats.push(s);
        }
    }
    data.record = roomInfo.allRecord;
    //同步整个信息给客户端
    clientMgr.sendMsg(userId,socket.resp.game_sync,data);
}

exports.get_tick_time = function(userId) {
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var roomInfo = roomMgr.getRoom(roomId);
    if(roomInfo == null){
        return null;
    }
    if(kickList[userId] == null || kickList[userId] <= 0) {
        var seatIndex = roomMgr.getUserIndex(userId);
        if (seatIndex == null || seatIndex == 0) {
            return kickList;
        }
        var s = roomInfo.seats[seatIndex];
        if (s.sit == 0 || (s.ready == 0 && roomInfo.conf.maxGames > 0)) {
            kickList[userId] = 120;
        }
        /*else if (s.ready == 0) {
            kickList[userId] = 120;
        }*/
    }
    return kickList;
}
exports.setNiuniu = function(userId) {
    db.niuniu_permission(userId,function (code) {
        if(code == 2)return;
        if(code == 1){
            clientMgr.sendMsg(userId, socket.resp.niuniu_resp,{code:1});
            return;
        }
        var roomId = roomMgr.getUserRoomId(userId);
        if(roomId == null){
            return;
        }
        var roomInfo = roomMgr.getRoom(roomId);
        if(roomInfo == null){
            return;
        }
        var seatIndex = roomMgr.getUserIndex(userId);
        if(seatIndex == null){
            return;
        }
        var s = roomInfo.seats[seatIndex];
        s.setNiuniu = true;
        clientMgr.sendMsg(userId, socket.resp.niuniu_resp,{code:0});
    })
}

function getNiuniu2(userId) {
    db.getNiuniu2(userId,function (rate) {
        var roomId = roomMgr.getUserRoomId(userId);
        if(roomId == null){
            return;
        }
        var roomInfo = roomMgr.getRoom(roomId);
        if(roomInfo == null){
            return;
        }
        var seatIndex = roomMgr.getUserIndex(userId);
        if(seatIndex == null){
            return;
        }
        var s = roomInfo.seats[seatIndex];
        s.setNiuniu2 = rate;
    })
}
exports.exitAfterEnd = function (roomInfo,seatIndex){
    // if(roomInfo.owner == "999999"){
        var game = games[ roomInfo.roomId ];
        if( game == null ) {
            return false;
        }
        else{
            roomInfo.seats[seatIndex].exitAfterEnd = true;
            return true;
        }
    // }
    return true;
}
function clearExit(roomInfo) {
    if (roomInfo == null) return;
    var roomId = roomInfo.roomId;
    for(var i = 0; i < roomInfo.seats.length; ++i) {
        var rs = roomInfo.seats[i];
        if(rs.exitAfterEnd) {// || clientMgr.isOnline(rs.userId) == false){
            if (rs.exitAfterEnd && roomMgr.isCreator(roomId, rs.userId)) {
                clientMgr.broadcastInRoom(socket.resp.dispress,"dispress",rs.userId,false);
                clientMgr.kickAllInRoom(roomId);
                roomMgr.destroy(roomId);
                return;
            }
            rs.exitAfterEnd = false;
            clientMgr.sendMsg(rs.userId,socket.resp.exit_result,rs.userId);
            //通知其它玩家，有人退出了房间
            clientMgr.broadcastInRoom(socket.resp.exit_notify,rs.userId,rs.userId,false);

            roomMgr.exitRoom(rs.userId);
        }
    }
}
//开始新的一局
function begin(roomId) {
    var state = {
        idle : 0,
        // qiangzhuang : 1,
        dingzhuang : 2,
        xiazhu : 3,
        // cuopai : 4,
        bipai : 5,
    };

    var roomInfo = roomMgr.getRoom(roomId);
    if(roomInfo == null || games[roomId] != null){
        return;
    }
    clearExit(roomInfo);

    var roomInfo = roomMgr.getRoom(roomId);
    if(roomInfo == null || games[roomId] != null){
        return;
    }

    roomMgr.payGameCost(roomId);

    var seats = roomInfo.seats;

    var game = {
        conf:roomInfo.conf,
        roomInfo:roomInfo,
        allState : state,

        qiangzhuangTime : 6,
        dingzhuangTime : 5,
        xiazhuTime : 15,
        cuopaiTime : 10,
        liangpaiTime  : 4,
        nextGameTime : 5,

        allCards : [],
        currentIndex:0,
        gameSeats:[],

        isNiuniu : false,
        button: 0,
        state:0,
        fundPool: 0,

        actionList:[],
    };
    roomInfo.numOfGames++;
    db.update_numOfGames(roomId,roomInfo.numOfGames);

    for(var i = 0; i < game.conf.roomNum; ++i) {
        if(seats[i].userId <= 0)continue;
        var data = game.gameSeats[i] = {};
        data.game = game;		//循环引用
        data.seatIndex = i;

        data.sit = seats[i].sit;
        data.userId = seats[i].userId;
        //持有的牌
        data.holds = [];

        data.score = 0;
        //抢庄倍数
        data.hasQiang = false;
        data.score1 = 0;
        //下注倍数
        data.hasXia = false;
        data.scoreBetting = 0;
        data.hasLiang = false;
        data.hasBetting = false;

        data.eliminate = false;

        // data.setNiuniu = seats[i].setNiuniu;
        // data.setNiuniu2 = seats[i].setNiuniu2;
        gameSeatsOfUsers[data.userId] = data;
    }

    var allHolds = [];
    var count = 0;
    for(var i = 0; i < seats.length; ++i) {
        if (!game.gameSeats[i]) continue;
        //开局时，通知前端必要的数据
        var s = seats[i];
        if(s.ready == 1){
            count += 1;
        }
    }
    if(count <= 1){
        if(roomInfo.owner != "999999"){
            // doGameOver2(game,roomId,true);
        }
        return;
    }
    roomInfo.gameState = "playing";
    clientMgr.broadcastInRoom2(socket.resp.game_state,{state:roomInfo.gameState},roomId);

    games[roomId] = game;
    //洗牌
    shuffle(game);
    //发牌
    deal(game);
    // createNiuniu2(game);
    // createNiuniu(game);

    for(var i = 0; i < seats.length; ++i) {
        //开局时，通知前端必要的数据
        var s = seats[i];
        //通知游戏开始
        clientMgr.sendMsg(s.userId, socket.resp.game_begin);

        var sd = game.gameSeats[i];
        if( sd == null || sd.sit == 0 || sd.userId <= 0) continue;
        
        //通知玩家手牌
        //var holds = utils.clone(game.gameSeats[i].holds);
        //holds[holds.length-1] = -1;
        //var data = {userId:s.userId,holds:holds};
        //clientMgr.sendMsg(s.userId, socket.resp.game_holds, [data]);
        allHolds.push({userId:s.userId,holds:game.gameSeats[i].holds,sit:s.sit});
        //通知还剩多少局
        clientMgr.sendMsg(s.userId, socket.resp.game_num, roomInfo.numOfGames);
        // 更新权限
        updatePermission(s.userId);
    }

    // var results = [];
    // game.fundPool += count * game.conf.difen;

    for(var i = 0; i < roomInfo.seats.length; ++i){
        var rs = roomInfo.seats[i];
        var sd = game.gameSeats[i];
        if( sd == null || sd.sit == 0 || sd.userId <= 0) continue;
        changeScore(game, sd, game.conf.difen);

        // rs.coins -= game.conf.difen;
        // rs.score -= game.conf.difen;
        // sd.score -= game.conf.difen;

        // var userRT = {
        //     userId:sd.userId,
        //     area : rs.area,
        //     coins:rs.coins,
        //     score:-game.conf.difen,
        // };
        // db.rate_coins(userRT);

        // results.push({
        //     userId:sd.userId,
        //     coins:rs.coins,
        //     score:-game.conf.difen,
        // });
    }

    for(var i = 0; i < seats.length; ++i) {
        var s = seats[i];
        var sd = game.gameSeats[i];
        if( sd == null || sd.sit == 0 || sd.userId <= 0) continue;
        var allHolds2 = utils.clone(allHolds);
        for(var j=0;j<allHolds2.length;j++){
            var holds = allHolds2[j].holds;
            // if(s.sit == 1 && s.userId == allHolds2[j].userId){
            //     allHolds2[j].holds = [-1, -1, -1];
            // }
            if(s.sit == 1) {
                allHolds2[j].holds = null;
            }
        }
        logger.game_log("当前手牌为", allHolds2);
        // clientMgr.sendMsg(s.userId,socket.resp.dizhu_cost,{results:results,fundPool:game.fundPool});
        clientMgr.sendMsg(s.userId, socket.resp.game_holds, allHolds2);
    }
    recordGameAction(game,socket.resp.game_begin);
    recordGameAction(game,socket.resp.game_holds,allHolds);
    recordGameAction(game,socket.resp.game_num,roomInfo.numOfGames);

    // game.state = game.allState.qiangzhuang;
    // clientMgr.broadcastInRoom2(socket.resp.qiangzhuang_all,{time:game.qiangzhuangTime},game.roomInfo.roomId,true);
    // recordGameAction(game,socket.resp.qiangzhuang_all,{time:game.qiangzhuangTime});
    setBanker(game);
    // game.timeId1 = setTimeout(function () {
    //     dingzhuang(game);
    // },game.qiangzhuangTime * 1000);
};

function setBanker(game){
    var indexArr = [];
    var userArr = [];
    for (var i=0;i<game.gameSeats.length;i++){
        var seatData = game.gameSeats[i];
        if(!seatData || seatData.sit == 0)continue;
        if(seatData.userId > 0){
            indexArr.push(i);
            userArr.push(seatData.userId);
        }
    }
    // 第一轮的庄家是随机的，后面的庄家都是上一轮的胜利者
    if (game.roomInfo.winnerIndex) {
        game.button = game.roomInfo.winnerIndex;
    } else {
        var random = Math.floor(Math.random()*indexArr.length);
        game.button = indexArr[random];
    }
    game.round = 0;
    game.callNowCost = game.conf.difen;  // 跟注费用
    game.betTop = game.conf.difen * 50; // 顶注

    var banker = game.gameSeats[game.button];   // 庄家
    game.state = game.allState.dingzhuang;
    
    clientMgr.broadcastInRoom2(socket.resp.dingzhuang_all,{time:game.dingzhuangTime,button:banker.userId,userArr:userArr},game.roomInfo.roomId,true);
    recordGameAction(game,socket.resp.dingzhuang_all,{time:game.dingzhuangTime,button:banker.userId,userArr:userArr});

    logger.game_log("准备开始下注");
    game.timeId2 = setTimeout(function () {
        logger.game_log("自动下注");
        game.turnGamber = game.button;
        betting(game);
    },game.dingzhuangTime * 1000);
}

function isGameOver(game) {
    var gamberNum = 0;
    for (var i = 0; i < game.gameSeats.length; ++i){
        var user = game.gameSeats[i];
        if (!user || user.sit == 0)continue;
        if (user.eliminate) continue;
        if (user.userId > 0){
            gamberNum += 1;
            if (gamberNum > 1) {
                return false;
            }
        }
    }
    return true;
}

function betting(game) {
    if (game.timerIdBetting != null) {
        clearTimeout(game.timerIdBetting);
    }
    if (game.button == game.turnGamber) {
        game.round += 1;
    }
    if (isGameOver(game)) {
        bipai(game);
        return;
    }

    var userSeatIndex = game.turnGamber;
    
    var gambler = game.gameSeats[userSeatIndex];
    if(!gambler || gambler.sit == 0) {
        logger.game_log("下注阶段有人跑路了");
        return;
    }

    var op = getOptionalOperate(game, userSeatIndex);
    let callNowCost = game.callNowCost;
    if (gambler.watchCardRound) {
        callNowCost *= 2;
    }
    let betTop = game.betTop;
    if (gambler.watchCardRound) {
        betTop *= 2;
    }
    var data = {time:game.xiazhuTime,gambler:gambler.userId,operates:op,callCost:callNowCost,betTop:betTop};
    clientMgr.broadcastInRoom2(socket.resp.zjh_turn_betting_notify,data,game.roomInfo.roomId,true);
    // recordGameAction(game,socket.resp.zjh_turn_betting_notify,data);

    game.state = game.allState.xiazhu;

    game.timerIdBetting = setTimeout(function () {
        exports.bettingWaive(gambler.userId);
    }, game.xiazhuTime * 1000);
}

function getOptionalOperate(game, userSeatIndex) {
    var gambler = game.gameSeats[userSeatIndex];
    if (gambler.watchCardRound != null) { // 如果看了牌
        if (game.round == 1) {
            return ZJHOptionalOperate.CALL_RAISE;
        } else {
            if (game.callNowCost >= game.betTop) {
                return ZJHOptionalOperate.COMPARE;
            } else {
                return ZJHOptionalOperate.CALL_RAISE_COMPARE;
            }
        }
    } else {
        if (game.round == 1) {
            return ZJHOptionalOperate.CALL_RAISE_WATCH;
        } else {
            if (game.callNowCost >= game.betTop) {
                return ZJHOptionalOperate.COMPARE_WATCH;
            } else {
                return ZJHOptionalOperate.CALL_RAISE_COMPARE_WATCH;
            }
        }
    }
}

function xiazhu(game){
    var sd = game.gameSeats[game.button];
    var score1 = sd.score1;
    clientMgr.broadcastInRoom2(socket.resp.xiazhu_all,{time:game.xiazhuTime,button:sd.userId,beishu:score1},game.roomInfo.roomId,true);
    recordGameAction(game,socket.resp.xiazhu_all,{time:game.xiazhuTime,button:sd.userId,beishu:score1});

    game.state = game.allState.xiazhu;
    game.timeId3 = setTimeout(function () {
        cuopai(game);
    },game.xiazhuTime * 1000);
}
function cuopai(game){
    if(game.timeId3 <= 0)return;
    game.timeId3 = -1;
    for (var i=0;i<game.gameSeats.length;i++){
        var ddd = game.gameSeats[i];
        if(!ddd || ddd.sit == 0)continue;
        if(ddd.score2 == 0  && i != game.button){
            ddd.score2 = 2;
            clientMgr.broadcastInRoom(socket.resp.xiazhu_notify,{userId:ddd.userId,value:2},ddd.userId,true);
            recordGameAction(game,socket.resp.xiazhu_notify,{userId:ddd.userId,value:2});
        }
        var niu = calculate(ddd.holds);
        clientMgr.sendMsg(ddd.userId, socket.resp.cuopai_all, {time:game.cuopaiTime,holds:ddd.holds,niu:niu});
    }

    game.state = game.allState.cuopai;
    game.timeId4 = setTimeout(function () {
        var turnSeat = game.gameSeats[game.button];
        bipai(game,turnSeat.userId);
    },game.cuopaiTime * 1000);
}
function bipai(game){
    if(game.timeId4 <= 0)return;
    game.timeId4 = -1;

    for (var l=0;l<game.gameSeats.length;l++) {
        var ddd = game.gameSeats[l];
        if (!ddd) continue;
        var niu = getCardType(ddd.holds);
        if(ddd.hasLiang == false){
            clientMgr.broadcastInRoom(socket.resp.liangpai_notify, {userId: ddd.userId,holds: ddd.holds,niu:niu,sit:ddd.sit},ddd.userId,true);
            recordGameAction(game, socket.resp.liangpai_notify, {userId: ddd.userId,holds: ddd.holds,niu:niu,sit:ddd.sit});
        }
        clientMgr.sendMsg(ddd.userId, socket.resp.bipai_all, {time:game.liangpaiTime});
    }

    game.state = game.allState.bipai;
    game.timeId5 = setTimeout(function () {
        var banker = game.gameSeats[game.button];
        doGameOver(game,banker.userId);
    },game.liangpaiTime * 1000);
}

exports.qiangzhuang = function (userId,value) {
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var seatIndex = roomMgr.getUserIndex(userId);
    if(seatIndex == null){
        return;
    }
    var game = games[ roomId ];
    if( game == null ) {
        return;
    }
    if(game.state != game.allState.qiangzhuang)return;

    var gs = game.gameSeats[seatIndex];
    gs.score1 = value;
    gs.hasQiang = true;
    clientMgr.broadcastInRoom(socket.resp.qiangzhuang_notify,{userId:userId,value:value},userId,true);
    recordGameAction(game,socket.resp.qiangzhuang_notify,{userId:userId,value:value});

    var hasOver = true;
    for (var i=0;i<game.gameSeats.length;i++) {
        var ddd = game.gameSeats[i];
        if(!ddd || ddd.sit == 0)continue;
        if(ddd.hasQiang == false){
            hasOver = false;
        }
    }
    if(hasOver){
        dingzhuang(game);
    }
}
function getNextUserIndex(game, userSeatIndex) {
    for (var i = 1; i < game.gameSeats.length; ++i){
        var index = (i + userSeatIndex) % game.gameSeats.length;
        var user = game.gameSeats[index];
        if (!user || user.sit == 0)continue;
        if (user.eliminate) {
            if (index == game.button) {
                game.round++;
            }
            continue;
        }
        if (user.userId > 0){
            return index;
        }
    }
}
function changeScore(game, gamber, value) {
    if( gamber == null || gamber.sit == 0 || gamber.userId <= 0) return;
    let userId = gamber.userId;
    var rs = roomMgr.getSeatUser(userId);

    rs.coins -= value;
    rs.score -= value;
    gamber.score -= value;
    game.fundPool += value;

    var userRT = {
        userId:userId,
        area : rs.area,
        coins:rs.coins,
        score:-value,
    };
    db.rate_coins(userRT);
    let results = [{userId:gamber.userId,score:-value,totalBetting:-gamber.score}];
    clientMgr.broadcastInRoom(socket.resp.dizhu_cost,{results:results,fundPool:game.fundPool},userId,true);
    recordGameAction(game,socket.resp.dizhu_cost,{results:results,fundPool:game.fundPool});
}
exports.bettingCall = function(userId) {
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var roomInfo = roomMgr.getRoom(roomId);
    if(roomInfo == null){
        return;
    }
    var seatIndex = roomMgr.getUserIndex(userId);
    if(seatIndex == null){
        return;
    }
    var game = games[ roomId ];
    if( game == null ) {
        return;
    }
    if(game.state != game.allState.xiazhu)return;
    if (game.turnGamber != seatIndex) return;   // 不是轮到这个用户下注
    var user = roomInfo.seats[seatIndex];
    var gamber = game.gameSeats[seatIndex];
    var value = gamber.watchCardRound ? game.callNowCost * 2 : game.callNowCost;
    let betTop = gamber.watchCardRound ? game.betTop * 2 : game.betTop;
    value = Math.min(value,betTop);
    logger.game_log("已有金币", user.coins, "打算下注", value);
    // if (value > user.coins) {
    //     logger.game_log("金币不足");
    //     recordGameAction(game,socket.resp.betting_call_notify,{userId:userId,value:value,failed:1});
    //     return;
    // }
    // game.callNowCost = value;
    gamber.hasBetting = true;
    gamber.scoreBetting += value;

    changeScore(game, gamber, value);

    clientMgr.broadcastInRoom(socket.resp.betting_call_notify,{userId:userId,value:value},userId,true);
    recordGameAction(game,socket.resp.betting_call_notify,{userId:userId,value:value});
    
    game.turnGamber = getNextUserIndex(game, game.turnGamber);
    betting(game);
}
exports.bettingRaise = function(userId, value) {
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var roomInfo = roomMgr.getRoom(roomId);
    if(roomInfo == null){
        return;
    }
    var seatIndex = roomMgr.getUserIndex(userId);
    if(seatIndex == null){
        return;
    }
    var game = games[ roomId ];
    if( game == null ) {
        return;
    }
    if(game.state != game.allState.xiazhu)return;
    if (game.turnGamber != seatIndex) return;   // 不是轮到这个用户下注
    var user = roomInfo.seats[seatIndex];
    var gamber = game.gameSeats[seatIndex];
    logger.game_log("已有金币", user.coins, "打算下注", value);
    // if (value > user.coins) {
    //     logger.game_log("金币不足");
    //     recordGameAction(game,socket.resp.betting_raise_notify,{userId:userId,value:value,failed:1});
    //     return;
    // }
    var callNowCost = gamber.watchCardRound ? game.callNowCost * 2 : game.callNowCost;
    let betTop = gamber.watchCardRound ? game.betTop * 2 : game.betTop;
    var minCost = Math.min(callNowCost, betTop);
    // var minCost = gamber.watchCardRound == game.round ? game.callNowCost * 2 : game.callNowCost;
    if (value > betTop || value < minCost) {
        logger.game_log("下注金额不正确", value, minCost, betTop);
        recordGameAction(game,socket.resp.betting_raise_notify,{userId:userId,value:value,failed:2});
        return;
    }
    if (gamber.watchCardRound) {
        game.callNowCost = Math.floor(value / 2);
    } else {
        game.callNowCost = value;
    }

    gamber.hasBetting = true;
    gamber.scoreBetting += value;

    changeScore(game, gamber, value);
    
    clientMgr.broadcastInRoom(socket.resp.betting_raise_notify,{userId:userId,value:value},userId,true);
    recordGameAction(game,socket.resp.betting_raise_notify,{userId:userId,value:value});
    
    game.turnGamber = getNextUserIndex(game, game.turnGamber);
    betting(game);
}
exports.bettingWaive = function(userId) {
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var roomInfo = roomMgr.getRoom(roomId);
    if(roomInfo == null){
        return;
    }
    var seatIndex = roomMgr.getUserIndex(userId);
    if(seatIndex == null){
        return;
    }
    var game = games[ roomId ];
    if( game == null ) {
        return;
    }
    if(game.state != game.allState.xiazhu)return;
    if (game.turnGamber != seatIndex) return;   // 不是轮到这个用户下注

    clientMgr.broadcastInRoom(socket.resp.betting_waive_notify,{userId:userId},userId,true);
    recordGameAction(game,socket.resp.betting_waive_notify,{userId:userId});
    
    var gamber = game.gameSeats[seatIndex];
    eliminateGamber(game, gamber);
    
    game.turnGamber = getNextUserIndex(game, game.turnGamber);
    betting(game);
}
exports.bettingWatch = function(userId) {
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var roomInfo = roomMgr.getRoom(roomId);
    if(roomInfo == null){
        return;
    }
    var seatIndex = roomMgr.getUserIndex(userId);
    if(seatIndex == null){
        return;
    }
    var game = games[ roomId ];
    if( game == null ) {
        return;
    }
    if(game.state != game.allState.xiazhu)return;
    if (game.turnGamber != seatIndex) return;   // 不是轮到这个用户下注
    var gamber = game.gameSeats[seatIndex];

    if (gamber.watchCardRound) {
        logger.game_log(userId, "已经看过牌了");
        return;
    }
    gamber.watchCardRound = game.round;
    
    var op = getOptionalOperate(game, seatIndex);
    clientMgr.sendMsg(userId, socket.resp.betting_watch_notify,{userId:userId,operates:op,holds:gamber.holds,callCost:game.callNowCost*2,betTop:game.betTop*2});
    clientMgr.broadcastInRoom(socket.resp.betting_watch_notify,{userId:userId,operates:op,holds:[-1,-1,-1],callCost:game.callNowCost*2,betTop:game.betTop*2},userId,false);
    recordGameAction(game,socket.resp.betting_watch_notify,{userId:userId,operates:op,holds:gamber.holds,callCost:game.callNowCost*2,betTop:game.betTop*2});
}
function eliminateGamber(game, gamber) {
    gamber.eliminate = true;
    logger.game_log(gamber.userId, "被淘汰");
    clientMgr.broadcastInRoom(socket.resp.eliminate_notify,{userId:gamber.userId},gamber.userId,true);
    recordGameAction(game,socket.resp.eliminate_notify,{userId:gamber.userId});
}

exports.bettingCompare = function(userId, cmpUserId) {
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var roomInfo = roomMgr.getRoom(roomId);
    if(roomInfo == null){
        return;
    }
    var seatIndex = roomMgr.getUserIndex(userId);
    if(seatIndex == null){
        return;
    }
    var game = games[ roomId ];
    if( game == null ) {
        return;
    }
    if(game.state != game.allState.xiazhu)return;
    if (game.turnGamber != seatIndex) return;   // 不是轮到这个用户下注
    var cmpSeatIndex = roomMgr.getUserIndex(cmpUserId);
    if (cmpSeatIndex == null) {
        return;
    }
    var gamber = game.gameSeats[seatIndex];
    var cmpGamber = game.gameSeats[cmpSeatIndex];
    if (gamber.eliminate) {
        return;
    }
    if (cmpGamber.eliminate) {
        var op = getOptionalOperate(game, userSeatIndex);
        let callNowCost = game.callNowCost;
        if (gamber.watchCardRound) {
            callNowCost *= 2;
        }
        let betTop = game.betTop;
        if (gamber.watchCardRound) {
            betTop *= 2;
        }
        var data = {time:0,gambler:gamber.userId,operates:op,callCost:callNowCost,betTop:betTop};
        clientMgr.broadcastInRoom2(socket.resp.zjh_turn_betting_notify,data,game.roomInfo.roomId,true);
        return;
    }
    var result = compare(gamber.holds, cmpGamber.holds) > 0 ? 1 : 0;
    
    var value = gamber.watchCardRound ? game.callNowCost * 2 : game.callNowCost;
    gamber.hasBetting = true;
    gamber.scoreBetting += value;
    changeScore(game, gamber, value);

    logger.game_log("比牌", userId, cmpUserId, result);
    clientMgr.broadcastInRoom(socket.resp.betting_compare_notify,{userId:userId,cmpUserId:cmpUserId,result:result},userId,true);
    recordGameAction(game,socket.resp.betting_compare_notify,{userId:userId,cmpUserId:cmpUserId,result:result});
    
    if (result == 1) {
        eliminateGamber(game, cmpGamber);
    } else {
        eliminateGamber(game, gamber);
    }

    game.turnGamber = getNextUserIndex(game, game.turnGamber);
    betting(game);
}
exports.xiazhu = function (userId,value) {
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var seatIndex = roomMgr.getUserIndex(userId);
    if(seatIndex == null){
        return;
    }
    var game = games[ roomId ];
    if( game == null ) {
        return;
    }
    if(game.state != game.allState.xiazhu)return;

    var gs = game.gameSeats[seatIndex];
    gs.score2 = value;
    gs.hasXia = true;
    clientMgr.broadcastInRoom(socket.resp.xiazhu_notify,{userId:userId,value:value},userId,true);
    recordGameAction(game,socket.resp.xiazhu_notify,{userId:userId,value:value});

    var hasOver = true;
    for (var i=0;i<game.gameSeats.length;i++) {
        var ddd = game.gameSeats[i];
        if(!ddd || i == game.button || ddd.sit == 0)continue;
        if(ddd.hasXia == false){
            hasOver = false;
        }
    }
    if(hasOver){
        cuopai(game);
    }
}
exports.kanpai = function (userId) {
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var seatIndex = roomMgr.getUserIndex(userId);
    if(seatIndex == null){
        return;
    }
    var game = games[ roomId ];
    if( game == null ) {
        return;
    }
    if(game.state != game.allState.cuopai)return;

    clientMgr.broadcastInRoom(socket.resp.kanpai_notify,{userId:userId},userId,true);
    recordGameAction(game,socket.resp.kanpai_notify,{userId:userId});
}
exports.liangpai = function (userId) {
    var roomId = roomMgr.getUserRoomId(userId);
    if(roomId == null){
        return;
    }
    var seatIndex = roomMgr.getUserIndex(userId);
    if(seatIndex == null){
        return;
    }
    var game = games[ roomId ];
    if( game == null ) {
        return;
    }
    if(game.state != game.allState.cuopai)return;

    var gs = game.gameSeats[seatIndex];
    if(gs.hasLiang)return;
    gs.hasLiang = true;

    var niu = calculate(gs.holds);
    clientMgr.broadcastInRoom(socket.resp.liangpai_notify,{userId:userId,holds: gs.holds,niu:niu,sit:gs.sit},userId,true);
    recordGameAction(game,socket.resp.liangpai_notify,{userId:userId,holds: gs.holds,niu:niu,sit:gs.sit});

    var hasOver = true;
    for (var i=0;i<game.gameSeats.length;i++) {
        var ddd = game.gameSeats[i];
        if(!ddd || ddd.sit == 0)continue;
        if(ddd.hasLiang == false){
            hasOver = false;
        }
    }
    if(hasOver){
        bipai(game,userId);
    }
}
function shuffle( game ) {
    let allCards = game.allCards;
    //初始化牌组
    for( let i = 1; i <= 13; i ++ ){
        for( let j = 1; j <= 4; j ++ ) {
            allCards.push("" + i + j);
        }
    }
    //数组重新排序
	for( let i = 0; i < allCards.length; ++i ) {
		let lastIndex = allCards.length - 1 - i;
		let index = Math.floor( Math.random() * lastIndex );
		let t = allCards[ index ];
        allCards[ index ] = allCards[ lastIndex ];
        allCards[ lastIndex ] = t;
	}
}
function deal(game){
    //强制清0
    game.currentIndex = 0;

    var seatIndex = 0;
    for(var i = 0; i < 3 * game.gameSeats.length; ++i){
        if(game.gameSeats[seatIndex] == null){
            seatIndex ++;
            seatIndex %= game.gameSeats.length;
            continue;
        }
        var holds = game.gameSeats[seatIndex].holds;
        if(holds == null){
            holds = [];
            game.gameSeats[seatIndex].holds = holds;
        }
        mopai(game,seatIndex);
        seatIndex ++;
        seatIndex %= game.gameSeats.length;
    }
}
function mopai( game, seatIndex ) {
    if(game.currentIndex == game.allCards.length){
        return -1;
    }
    var data = game.gameSeats[seatIndex];
    var holds = data.holds;
    var pai = game.allCards[game.currentIndex];
    game.currentIndex ++;
    holds.push( pai );
    return pai;
}
// function createNiuniu( game ) {
//     var setNiuniu = false;
//     var index = -1;
//     for(var i = 0; i < game.gameSeats.length; ++i){
//         if(game.gameSeats[i] == null){
//             continue;
//         }
//         var seats = game.gameSeats[i];
//         if(seats.setNiuniu){
//             game.roomInfo.seats[i].setNiuniu = false;
//             setNiuniu = true;
//             index = i;
//         }
//     }

//     if(setNiuniu == false) return;
//     var maxIndex = -1;
//     var maxNiu = -1;
//     var maxNiuArr = [];
//     for(var i = 0; i < game.gameSeats.length; ++i) {
//         if (game.gameSeats[i] == null) {
//             continue;
//         }
//         var holds = game.gameSeats[i].holds;
//         var value = calculate(holds);
//         if(value > maxNiu){
//             maxNiu = value;
//             maxNiuArr = [i];
//         }
//         else if(value == maxNiu){
//             maxNiuArr.push(i);
//         }
//     }
//     if(maxNiuArr.length == 1){
//         maxIndex = maxNiuArr[0];
//     }
//     else{
//         var temp = maxNiuArr[0];
//         var seatData = game.gameSeats[temp];
//         for(var j = 1; j < maxNiuArr.length; ++j){
//             seatData = game.gameSeats[temp];
//             var sd = game.gameSeats[maxNiuArr[j]];
//             var result = compare(seatData.holds,sd.holds,maxNiu);
//             if(result < 0){
//                 temp = maxNiuArr[j];
//             }
//         }
//         maxIndex = temp;
//     }

//     var holds_temp = game.gameSeats[index].holds;
//     game.gameSeats[index].holds = game.gameSeats[maxIndex].holds;
//     game.gameSeats[maxIndex].holds = holds_temp;
// }

// function createNiuniu2( game ) {
//     var setNiuniu = false;
//     var index1 = -1;
//     var index2 = -1;
//     for(var i = 0; i < game.gameSeats.length; ++i){
//         if(game.gameSeats[i] == null){
//             continue;
//         }
//         var seats = game.gameSeats[i];
//         var rate = seats.setNiuniu2;
//         if(rate == 0)continue;
//         var rate2 = Math.abs(rate);
//         var randNum = Math.random() * 100;
//         logger.game_log("Control:",rate2,randNum);
//         if(randNum < rate2){
//             if(rate > 0) {
//                 index1 = i;
//             }
//             else{
//                 index2 = i;
//             }
//             setNiuniu = true;
//         }
//     }
//     if(setNiuniu == false) return;
//     var maxIndex = -1;
//     var maxNiu = -1;
//     var minIndex = 0;
//     var minNiu = 10;
//     var maxNiuArr = [];
//     for(var i = 0; i < game.gameSeats.length; ++i) {
//         if (game.gameSeats[i] == null) {
//             continue;
//         }
//         var holds = game.gameSeats[i].holds;
//         var value = calculate(holds);
//         if(value > maxNiu){
//             maxNiu = value;
//             maxNiuArr = [i];
//         }
//         else if(value == maxNiu){
//             maxNiuArr.push(i);
//         }
//         if(value < minNiu){
//             minNiu = value;
//             minIndex = i;
//         }
//     }
//     if(maxNiuArr.length == 1){
//         maxIndex = maxNiuArr[0];
//     }
//     else{
//         var temp = maxNiuArr[0];
//         var seatData = game.gameSeats[temp];
//         for(var j = 1; j < maxNiuArr.length; ++j){
//             seatData = game.gameSeats[temp];
//             var sd = game.gameSeats[maxNiuArr[j]];
//             var result = compare(seatData.holds,sd.holds,maxNiu);
//             if(result < 0){
//                 temp = maxNiuArr[j];
//             }
//         }
//         maxIndex = temp;
//     }

//     if(index1 > 0){
//         var holds_temp = game.gameSeats[index1].holds;
//         game.gameSeats[index1].holds = game.gameSeats[maxIndex].holds;
//         game.gameSeats[maxIndex].holds = holds_temp;
//     }
//     if(index2 > 0 && index2 != minIndex){
//         var holds_temp2 = game.gameSeats[index2].holds;
//         game.gameSeats[index2].holds = game.gameSeats[minIndex].holds;
//         game.gameSeats[minIndex].holds = holds_temp2;
//     }
// }


// 获取花色
function getCardDecor(card) {
    return Number(card % 10);
}

// 获取牌的值
function getCardValue(card) {
    return Number(Math.floor(card / 10));
}

//顺子
function isStraight(cards) {
    var dict = {};
    var minValue = 99;
    var maxValue = 0;
    for (var i = 0; i < cards.length; i++) {
        var value = getCardValue(cards[i]);
        if (value < minValue) {
            minValue = value;
        }
        if (value > maxValue) {
            maxValue = value;
        }
        if (dict[value]) {  // 有对子或者豹子，肯定不是顺子
            return false;
        }
        dict[value] = 1;
    }
    
    if ((maxValue - minValue + 1) == cards.length) {    // A23 ~ JQK
        return true;
    }

    if (dict[12] && dict[13] && dict[1]) {  // QKA
        return true;
    }
    return false;
}
//同花
function isSameDecor(cards) {
    var decor;
    for (var i = 0; i < cards.length; i++) {
        var type = getCardDecor(cards[i]);
        if(decor == null){
            decor = type;
        }
        else if(type != decor){
            return false;
        }
    }
    return true;
}

// 同花顺
function isSameDecorStraight(cards) {
    if (!isSameDecor(cards)) {
        return false;
    }
    if (!isStraight(cards)) {
        return false;
    }
    return true;
}

// 豹子
function isLeopard(cards) {
    var firstValue;
    for (var i = 0; i < cards.length; i++) {
        var value = getCardValue(cards[i]);
        if(firstValue == null){
            firstValue = value;
        }
        else if(value != firstValue){
            return false;
        }
    }
    return true;
}
// //葫芦牛
// function checkHulu( cards ) {
//     var dict = {};
//     for (var i = 0; i < cards.length; i++) {
//         var card = parseInt(cards[i]);
//         var value = Math.floor(card / 10);
//         dict[value] = dict[value] === undefined ? 1 : dict[value] + 1;
//     }
//     var count = [];
//     for (var i in dict) {
//         count.push(dict[i]);
//     }
//     if(count.length == 2 && (count[0] == 3 || count[1] == 3)){
//         logger.game_log("葫芦牛22222222222222222222",count,cards);
//         return true;
//     }
//     return false;
// }
// //炸弹牛
// function checkZhadan( cards ) {
//     var dict = {};
//     for (var i = 0; i < cards.length; i++) {
//         var card = parseInt(cards[i]);
//         var value = Math.floor(card / 10);
//         dict[value] = dict[value] === undefined ? 1 : dict[value] + 1;
//     }
//     var count = [];
//     for (var i in dict) {
//         count.push(dict[i]);
//     }
//     if(count.length == 2 && (count[0] == 4 || count[1] == 4)){
//         logger.game_log("炸弹牛2222222222222222222",count,cards);
//         return true;
//     }
//     return false;
// }
// //五小牛
// function checkWuxiao( cards ) {
//     var total = 0;
//     for (var i = 0; i < cards.length; i++) {
//         var card = parseInt(cards[i]);
//         var value = Math.floor(card / 10);
//         total += value;
//     }
//     if(total <= 10)return true;
//     return false;
// }
// //五花牛
// function checkWuhua( cards ) {
//     var isWuhuaniu = true;
//     for (var i = 0; i < cards.length; i++) {
//         var card = parseInt(cards[i]);
//         if(card <= 104){
//             isWuhuaniu = false;
//         }
//     }
//     return isWuhuaniu;
// }

function isSpecialCard(cards) {
    var dict = {};
    var decorDict = {}
    for (var i = 0; i < cards.length; ++i) {
        var decor = getCardDecor(cards[i]);
        if (decorDict[decor]) return false;
        decorDict[decor] = 1;

        var value = getCardValue(cards[i]);
        dict[value] = dict[value] ? dict[value] + 1 : 1;
    }
    if (!dict[2] || !dict[3] || !dict[5]) {
        return false;
    }
    return true;
}

function getMixCardPoint(cards) {
    var dict = {};
    for (var i = 0; i < cards.length; ++i) {
        var value = getCardValue(cards[i]);
        dict[value] = dict[value] ? dict[value] + 1 : 1;
    }

    var point = 0;
    for (var i = 14; i >= 2; --i) {
        var value = i > 13 ? i - 13 : i;
        while (dict[value] && dict[value] > 0) {
            --dict[value];
            point = point * 100 + i;
        }
    }
    return point;
}

function isPair(cards) {
    var dict = {};
    for (var i = 0; i < cards.length; ++i) {
        var value = getCardValue(cards[i]);
        dict[value] = dict[value] ? dict[value] + 1 : 1;
    }
    for (var i = 1; i <= 13; ++i) {
        if (dict[i] && dict[i] >= 2) {
            return true;
        }
    }
    return false;
}

function getPairPoint(cards) {
    var dict = {};
    for (var i = 0; i < cards.length; i++) {
        var value = getCardValue(cards[i]);
        dict[value] = dict[value] ? dict[value] + 1 : 1;
    }
    var pairValue;
    for (let i = 14; i > 1; --i) {
        let value = i > 13 ? i - 13 : i;
        if (dict[value] >= 2) {
            pairValue = i;
            break;
        }
    }
    if (pairValue == null) return 0;

    var point = pairValue * 100 + pairValue;

    for (let i = 14; i > 1; --i) {
        let value = i > 13 ? i - 13 : i;
        if (i == pairValue) continue;
        while (dict[value] && dict[value] > 0) {
            --dict[value];
            point = point * 100 + i;
        }
    }
    
    return point;
}

//计算最终为牛几
function calculate(cards) {
    if (isLeopard(cards)) {
        return 9000000 + getMixCardPoint(cards);
    }
    if (isSameDecorStraight(cards)) {
        return 8000000 + getMixCardPoint(cards);
    }
    if (isSameDecor(cards)) {
        return 7000000 + getMixCardPoint(cards);
    }
    if (isStraight(cards)) {
        return 6000000 + getMixCardPoint(cards);
    }
    if (isPair(cards)) {
        return 5000000 + getPairPoint(cards);;
    }
    return getMixCardPoint(cards);

    // var isShunzi = checkShunzi(cards);
    // var isTonghua = checkTonghua(cards);
    // if(isShunzi && isTonghua)return 17;
    // if(checkZhadan(cards))return 16;
    // if(checkWuhua(cards))return 15;
    // if(checkWuxiao(cards))return 14;
    // if(checkHulu(cards))return 13;
    // if(isTonghua)return 12;
    // if(isShunzi)return 11;

    // var s = 0;
    // var dict = {};
    // for (var i = 0; i < cards.length; i++) {
    //     var card = parseInt(cards[i]);
    //     var ci = Math.floor(card / 10);
    //     if(ci > 10)ci = 10;
    //     s += ci;
    //     dict[ci] = dict[ci] === undefined ? 1 : dict[ci] + 1;
    // };
    // var point = s % 10;

    // var exists = false;
    // for (var i in dict) {
    //     var other = (10 + point - i) % 10;
    //     if(other == 0)other = 10;
    //     if (dict[other]) {
    //         if ((other == i && dict[other] >= 2) || (other!=i&&dict[other] >= 1)) {
    //             exists = true;
    //             break;
    //         }
    //     }
    // }
    // if(point == 0){
    //     point = 10;
    // }
    // return exists ? point : -1;
}

function getCardType(cards) {
    if (isLeopard(cards)) {
        return 15;
    }
    if (isSameDecorStraight(cards)) {
        return 14;
    }
    if (isSameDecor(cards)) {
        return 13;
    }
    if (isStraight(cards)) {
        return 12;
    }
    if (isPair(cards)) {
        return 11;
    }
    return 0;
}
// function typeResult(point){
//     var beishu = 1;
//     if(point == 7 || point == 8){
//         beishu = 2;
//     }
//     else if(point == 9){
//         beishu = 3;
//     }
//     else if(point == 10){
//         beishu = 4;
//     }
//     else if(point > 10){
//         beishu = 5;
//     }
//     return beishu;
// }

function compare(holds1, holds2) {
    if (isSpecialCard(holds1) && isLeopard(holds2)) return 1;
    if (isSpecialCard(holds2) && isLeopard(holds1)) return -1;
    var point1 = calculate(holds1);
    var point2 = calculate(holds2);
    logger.game_log(holds1, "得分为", point1);
    logger.game_log(holds2, "得分为", point2);
    if (point1 > point2) {
        return 1;
    } else if (point1 == point2) {
        return 0;
    } else {
        return -1;
    }
}
// function compare(holds1,holds2,point){
//     //葫芦和炸弹特殊
//     if(point == 13 || point == 15){
//         var dict1 = {};
//         for (var i = 0; i < holds1.length; i++) {
//             var card = parseInt(holds1[i]);
//             var value = Math.floor(card / 10);
//             dict1[value] = dict1[value] === undefined ? 1 : dict1[value] + 1;
//         }
//         var hold1 = 0;
//         var count1 = 0;
//         for (var i in dict1) {
//             if(dict1[i] > count1){
//                 count1 = dict1[i];
//                 hold1 = i;
//             }
//         }
//         var dict2 = {};
//         for (var i = 0; i < holds2.length; i++) {
//             var card = parseInt(holds2[i]);
//             var value = Math.floor(card / 10);
//             dict2[value] = dict2[value] === undefined ? 1 : dict2[value] + 1;
//         }
//         var hold2 = 0;
//         var count2 = 0;
//         for (var i in dict2) {
//             if(dict2[i] > count2){
//                 count2 = dict2[i];
//                 hold2 = i;
//             }
//         }
//         return hold1 - hold2;
//     }
//     var maxType1 = 0;
//     var maxValue1 = 0;
//     var maxType2 = 0;
//     var maxValue2 = 0;
//     for(var i=0;i<holds1.length;i++){
//         var value = Math.floor(holds1[i] / 10);
//         var type = holds1[i] % 10;
//         if(value > maxValue1){
//             maxValue1 = value;
//             maxType1 = type;
//         }
//         else if(value == maxValue1 && type < maxType1){
//             maxType1 = type;
//         }
//     }
//     for(var i=0;i<holds2.length;i++){
//         var value = Math.floor(holds2[i] / 10);
//         var type = holds2[i] % 10;
//         if(value > maxValue2){
//             maxValue2 = value;
//             maxType2 = type;
//         }
//         else if(value == maxValue2 && type < maxType2){
//             maxType2 = type;
//         }
//     }
//     if(maxValue1 > maxValue2){
//         return 1;
//     }
//     else if(maxValue1 == maxValue2){
//         if(maxType1 < maxType2){
//             return 1;
//         }
//         else{
//             return -1;
//         }
//     }
//     else if(maxValue1 < maxValue2){
//         return -1;
//     }
// }
function calculateResult(game,roomInfo){
    var winner = null;
    var winValue = 0;
    var specialCardsGamber = null;

    for (var i = 0; i < game.gameSeats.length; ++i) {
        var index = (i + game.button) % game.gameSeats.length;  // 从庄家开始轮
        var gamber = game.gameSeats[index];
        if (gamber == null || gamber.sit == 0) continue;
        if (gamber.eliminate) continue;     // 玩家被淘汰了
        var value = calculate(gamber.holds);
        gamber.niu = getCardType(gamber.holds);
        logger.game_log("玩家", gamber.userId, "的手牌是", gamber.holds, "得分是", value);
        if (winner == null || value > winValue) {
            winner = gamber;
            winValue = value;
        }

        if (!specialCardsGamber && (isSpecialCard(gamber.holds))) {
            specialCardsGamber = gamber;
        }
    }

    if (winner == null) {
        for (var i = 1; i < game.gameSeats.length; ++i) {
            var index = (game.gameSeats.length - i + game.button) % game.gameSeats.length;  // 从庄家开始轮
            var gamber = game.gameSeats[index];
            // logger.game_log("全弃:", gamber);
            if (gamber == null || gamber.sit == 0) continue;
            winner = gamber;
            break;
        }
    } else {
        if (specialCardsGamber != null && isLeopard(winner.holds)) {
            winner = specialCardsGamber;
        }
    }
    // 定庄
    for (var i = 0; i < game.gameSeats.length; ++i) {
        if (game.gameSeats[i] == winner) {
            roomInfo.winnerIndex = i;
        }
    }

    // for (var i = 0; i < game.gameSeats.length; ++i) {
    //     var gamber = game.gameSeats[i];
    //     if (gamber == null || gamber.sit == 0) continue;
        
    //     if (winner != gamber) {
    //         gamber.score = -gamber.scoreBetting;
    //         winner.score += gamber.scoreBetting;
    //     }
    // }
    // winner.score += game.fundPool;
    changeScore(game, winner, -game.fundPool);
}

function doGameOver(game,userId,forceEnd){
    var roomId = roomMgr.getUserRoomId(userId);
    doGameOver2(game,roomId,forceEnd);
}
function doGameOver2(game,roomId,forceEnd){
	if(roomId == null){
		return;
	}
	var roomInfo = roomMgr.getRoom(roomId);
	if(roomInfo == null){
		return;
	}
	roomInfo.gameState = "idle";
    clientMgr.broadcastInRoom2(socket.resp.game_state,{state:roomInfo.gameState},roomId);

	var results = [];
    var dbusers = [];
	var dbresult = [];
    var backcount = 0,renshu = 0;
    var isEnd = false;
    var endInfo = null;

	if(game != null){
	    if(!forceEnd){
			calculateResult(game,roomInfo);	
		}

        if(roomInfo.allRecord == null){
	        roomInfo.allRecord = [];
            roomInfo.allRecord[0] = {};
        }
        var record;
        if(roomInfo.conf.maxGames > 0){
            record = roomInfo.allRecord[roomInfo.numOfGames] = {};
        }
        else{
            record = roomInfo.allRecord = {};
        }
        var endTime = Date.now();
        var cost_coins = function (data,rs) {
            db.rate_coins(data,function (info) {
                var difen = game.conf.difen;
                // if(info.coins <= difen){
                //     rs.sit = 0;
                //     exports.sitDown(rs.userId,false);
                // }
                data.coins = info.coins;
                data.score = -1 * info.cost;
                record[data.userId].score = -1 * info.cost;
                backcount ++;

                //如果局数已够，则进行整体结算，并关闭房间
                if(backcount >= renshu){
                    clientMgr.broadcastInRoom2(socket.resp.game_over,{results:results,endInfo:endInfo,endTime:endTime,record:record},roomId);
                    if(isEnd){
                        // clientMgr.broadcastInRoom2(socket.resp.dispress,"dispress",roomId);
                        clientMgr.kickAllInRoom(roomId);
                        roomMgr.destroy(roomId);
                    }
                }
            });
        }
		for(var i = 0; i < roomInfo.seats.length; ++i){
			var rs = roomInfo.seats[i];
			var sd = game.gameSeats[i];
            if(rs.shangzhuang == null){
                rs.shangzhuang = 0;
            }
            if(rs.niuniu == null){
                rs.niuniu = 0;
            }
            if(rs.win == null){
                rs.win = 0;
            }
			if( sd == null || sd.sit == 0 || sd.userId <= 0) continue;
            renshu ++;
            rs.shangzhuang += game.button == i?1:0;
            rs.niuniu += sd.isNiuniu?1:0;
            rs.win += sd.score > 0?1:0;

			// rs.coins += sd.score;
            // rs.score += sd.score;
            rs.ready = false;

            record[sd.userId] = {score:sd.score,holds:sd.holds,niu:sd.niu,isZhuang:game.button == i};

			var userRT = {
				userId:sd.userId,
                area : rs.area,
                coins:rs.coins,
                score:sd.score,
			};
			// results.push(userRT);
            dbusers.push(sd.userId);
			dbresult.push(sd.score);
			sd.game = null;	//清除数据
			delete gameSeatsOfUsers[sd.userId];

            // logger.game_log("计算金币", userRT, rs);
            cost_coins(userRT,rs);
		}
		delete games[roomId];
	}
    var fnNoticeResult = function(isEnd){
        roomInfo.settle = roomInfo.settle || {};
        for(var i = 0; i < roomInfo.seats.length; ++i){
            var rs = roomInfo.seats[i];
            if(rs.userId <= 0)continue;
            if(rs.shangzhuang == null){
                rs.shangzhuang = 0;
            }
            if(rs.niuniu == null){
                rs.niuniu = 0;
            }
            if(rs.win == null){
                rs.win = 0;
            }
            roomInfo.settle[rs.userId] = {
                userId:rs.userId,
                score:rs.score,
                shangzhuang:rs.shangzhuang,
                niuniu:rs.niuniu,
                win:rs.win,
            };
        }
        if(isEnd){
            endInfo = [];
            for (let userId in roomInfo.settle) {
                endInfo.push(roomInfo.settle[userId]);
            }
        }

        if( isEnd ){
            if( roomInfo.numOfGames > 1) {
                store_history(game,roomInfo);
            }
        }
        else{
            setTimeout(function() {
                clearExit(roomInfo);
            }, 2000);

            clientMgr.broadcastInRoom2(socket.resp.next_all,{time:game.nextGameTime},roomId,true);
            recordGameAction(game,socket.resp.next_all,{time:game.nextGameTime});
            game.state = game.allState.idle;
            game.timeId5 = setTimeout(function () {
                var game = games[ roomId ];
                if( game == null ) {
                    begin(roomId);
                }
            },game.nextGameTime * 1000);
        }
    }
	if(forceEnd || game == null){
        isEnd = true;
		fnNoticeResult(true);
        clientMgr.broadcastInRoom2(socket.resp.dispress,"dispress",roomId);
        clientMgr.kickAllInRoom(roomId);
        roomMgr.destroy(roomId);
	}
	else{
        isEnd = (roomInfo.numOfGames >= roomInfo.conf.maxGames) && roomInfo.conf.maxGames > 0;
        fnNoticeResult(isEnd);

        //记录打牌信息
        db.insert_game_records(roomId,roomInfo.type,roomInfo.createTime,roomInfo.numOfGames,dbusers,dbresult,game.actionList);
	}
}

function recordGameAction(game,cmd,result){
	game.actionList.push({cmd:cmd,result:result});
}

function store_history(game,roomInfo){
	var seats = roomInfo.seats;
	var history = {
		roomId:roomInfo.roomId,
        type : roomInfo.type,
        owner : roomInfo.owner,
        index : roomInfo.numOfGames,
		time:roomInfo.createTime,
        conf:roomInfo.conf,
        url : roomInfo.url,
		seats:[]
	};

	for(var i = 0; i < seats.length; ++i){
		var rs = seats[i];
		if(rs.userId <= 0){
		    continue;
        }
        var hs = history.seats[i] = {};
		hs.userId = rs.userId;
		hs.name = crypto.fromBase64(rs.userName);
		hs.score = rs.score;
	}
	db.store_history(history);
}

exports.hasBegan = function(roomId){
	var game = games[roomId];
	if(game && game.state != 0){
		return true;
	}
	// var roomInfo = roomMgr.getRoom(roomId);
	// if(roomInfo != null){
    //     return roomInfo.gameState == "playing";
	// 	// return roomInfo.numOfGames > 0;
	// }
	return false;
};

function updatePermission(userId) {
    db.niuniu_permission(userId, function(times) {
        if (times != 0) {
            console.warn(userId, "没有权限");
            return ;
        }
        
        clientMgr.sendMsg(userId, socket.resp.update_permission);
    });
}

exports.perspective = function(roomId, userId){
	var game = games[roomId];
	if(game == null){
		return;
	}
	var roomInfo = roomMgr.getRoom(roomId);
	if(roomInfo == null){
		return;
	}
    db.niuniu_permission(userId, function(times) {
        if (times != 0) {
            console.warn(userId, "想要透视，没有权限");
            return ;
        }
        var seats = roomInfo.seats;
        var allHolds = [];
        for(var i = 0; i < seats.length; ++i) {
            if (!game.gameSeats[i]) continue;
            allHolds.push({userId:seats[i].userId,holds:game.gameSeats[i].holds});
        }
        logger.game_log("透视的牌", allHolds);
        clientMgr.sendMsg(userId, socket.resp.perspective, allHolds);
        recordGameAction(game,socket.resp.perspective,allHolds);
    });
};

exports.replaceCardGet = function(roomId, userId){
	var game = games[roomId];
	if(game == null){
		return;
	}
	var roomInfo = roomMgr.getRoom(roomId);
	if(roomInfo == null){
		return;
	}
    db.niuniu_permission(userId, function(times) {
        if (times != 0) {
            console.warn(userId, "想要看牌堆，没有权限");
            return ;
        }
        var holds = [];
        for (var i = game.currentIndex; i < game.allCards.length; ++i) {
            holds.push(game.allCards[i]);
        }
        clientMgr.sendMsg(userId, socket.resp.replace_card_get, holds);
        recordGameAction(game,socket.resp.replace_card_get,holds);
    });
}

exports.replaceCardSet = function(roomId, userId, hold, target){
	var game = games[roomId];
	if(game == null){
		return;
	}
	var roomInfo = roomMgr.getRoom(roomId);
	if(roomInfo == null){
		return;
	}
    
    db.niuniu_permission(userId, function(times) {
        if (times != 0) {
            console.warn(userId, "想要换牌，没有权限");
            return ;
        }
        
        var findCardIndex = function(cards, card, startIndex=0) {
            for (var i = startIndex; i < cards.length; ++i) {
                if (cards[i] == card) {
                    return i;
                }
            }
            return -1;
        }
        var cardIndex = findCardIndex(game.allCards, target, game.currentIndex);
        if (cardIndex == -1) {
            logger.game_log(userId, "要替换的目标牌不存在", hold, target);
            return;
        }

        var seatIndex = roomMgr.getUserIndex(userId);
        var holds = game.gameSeats[seatIndex].holds;
        var holdIndex = findCardIndex(holds, hold);
        if (holdIndex == -1) {
            logger.game_log(userId, "要替换的手牌不存在", hold, target);
            return;
        }
        holds[holdIndex] = target;
        game.allCards[cardIndex] = hold;
        
        clientMgr.sendMsg(userId, socket.resp.replace_card_set, holds);
        recordGameAction(game,socket.resp.replace_card_set, holds);
    });
}

function update() {
    for(var userId in kickList) {
        kickList[userId] -= 1;
        var roomId = roomMgr.getUserRoomId(userId);
        if(roomId == null){
            delete kickList[userId];
            continue;
        }
        var roomInfo = roomMgr.getRoom(roomId);
        if(roomInfo == null){
            delete kickList[userId];
            continue;
        }
        if(kickList[userId] < 0){
            clientMgr.sendMsg(userId,socket.resp.exit_result,userId);
            //通知其它玩家，有人退出了房间
            clientMgr.broadcastInRoom(socket.resp.exit_notify,userId,userId,false);
            roomMgr.exitRoom(userId);
            delete kickList[userId];
        }
    }
}
setInterval( update, 1000 );


